package com.wy._05Random;

import java.util.HashMap;
import java.util.Set;

/**
 * 返回随机数字，包括整数型，小数，以及多种格式的数字
 */
public class RandomFigure {
    /**
     * @return 随机生成一个0-100的整数，包含0和100
     */
    public static int RandomInt() {
        return RandomInt(0, 100);
    }

    /**
     * @return 随机生成一个0-100的浮点数，默认两位小数，包含边界
     */
    public static double RandomDouble() {
        double v = RandomDouble(2, 0, 100);
        return v;
    }

    /**
     * @param min 最小边界
     * @param max 最大边界
     * @return 随机生成某一个范围内的整数，包含边界
     */
    public static int RandomInt(int min, int max) {
        return (int) (Math.random() * (max - min + 1) + min);
    }

    /**
     * @param decimalNumber 小数位数
     * @param min           最小值
     * @param max           最大值
     * @return 返回某个范围内固定位数的随机小数
     */
    public static double RandomDouble(int decimalNumber, double min, double max) {
        double infinitelySmall = 0.0000000001;
        double randomFigure = (Math.random() * (max - min)) + min + infinitelySmall;
        String format = "%." + (decimalNumber + "") + "f";
        String formatFinal = String.format(format, randomFigure);
        return Double.parseDouble(formatFinal);
    }

    /**
     * @param near 输入某个数
     * @return 返回某个数附近的随机数，中奖不就是这么回事儿
     */
    public static double RandomDouble(double near) {
        double min = 0.9 * near;
        double max = 1.1 * near;
        int numberDecimalDigits = getNumberDecimalDigits(near);
        double v = RandomDouble(numberDecimalDigits, min, max);
        return v;
    }

    /**
     * @param number 传入一个数字
     * @return 得到小数位数
     * 因为double的精度丢失问题，所以这个问题并不简单
     */
    public static int getNumberDecimalDigits(double number) {
        String moneyStr = String.valueOf(number);
        String[] num = moneyStr.split("\\.");
        if (num.length == 2) {
            for (; ; ) {
                if (num[1].endsWith("0")) {
                    num[1] = num[1].substring(0, num[1].length() - 1);
                } else {
                    break;
                }
            }
            return num[1].length();
        } else {
            return 0;
        }
    }

    /**
     * @return 返回一个随机浮点数数组，数组长度(1-20),数字(0-100)
     */
    public static double[] RandomDoubleArray() {
        double[] arr = new double[RandomInt(1, 20)];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = RandomDouble();
        }
        return arr;
    }

    /**
     * @return 返回 随机整数数组, 数组长度随机(1-20)
     */
    public static int[] RandomIntArray() {
        int[] arr = new int[RandomInt(1, 20)];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = RandomInt();
        }
        return arr;
    }

    /**
     * @param arr 传入一个数组
     * @return 返回此数组的随机排序数组
     */
    public static int[] ArrayRandomSort(int[] arr) {
        int[] ints = new int[arr.length];
        HashMap<Integer, int[]> integerHashMap = null;
        for (int i = 0; i < ints.length; i++) {
            integerHashMap = RandomArrayAndFigure(arr);
            Set<Integer> integers = integerHashMap.keySet();
            for (Integer integer : integers) {
                ints[i] = integer;
                arr = integerHashMap.get(integer);
            }
        }
        return ints;
    }

    /**
     * @param arr 传入一个数组
     * @return 返回这个数组的随机排序doule类型
     */
    public static double[] ArrayRandomSort(double[] arr) {
        double[] doubles = new double[arr.length];
        HashMap<Double, double[]> integerHashMap = null;
        for (int i = 0; i < doubles.length; i++) {
            integerHashMap = RandomArrayAndFigure(arr);
            Set<Double> doubles1 = integerHashMap.keySet();
            for (Double dou : doubles1) {
                doubles[i] = dou;
                arr = integerHashMap.get(dou);
            }
        }
        return doubles;
    }

    /**
     * @param length 数组长度
     * @param min    数组可能最小值
     * @param max    数组可能最大值
     * @return 返回指定数组
     */
    public static int[] getIntArray(int length, int min, int max) {
        int[] arr = new int[length];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = RandomInt(min, max);
        }
        return arr;
    }

    /**
     * @param length 数组长度
     * @param min    数组可能最小值
     * @param max    数组可能最大值
     * @return 返回指定数组，数组的小数长度为出传入的连个参数的最长小数长度
     */
    public static double[] getDoubleArray(int length, double min, double max) {
        double[] arr = new double[length];
        int DecimalDigits = Math.max(getNumberDecimalDigits(min), getNumberDecimalDigits(max));
        for (int i = 0; i < arr.length; i++) {
            arr[i] = RandomDouble(DecimalDigits, min, max);
        }
        return arr;
    }

    /**
     * @param arr 传入一个数组
     * @return 随机返回此数组中的一个数，其实就是随机了一个索引，返回的是数组随机索引对应的值
     */
    public static int RandomArrayFigure(int[] arr) {
        int i = RandomInt(0, arr.length - 1);
        return arr[i];
    }

    /**
     * @param arr 传入一个数组，
     * @return 返回一个值和数组的 集合 为什么返回值，因为这个值是hashmap的键，可以根据这个键查value
     */
    public static HashMap<Integer, int[]> RandomArrayAndFigure(int[] arr) {
        HashMap<Integer, int[]> hm = new HashMap<>();
        int[] ints = new int[arr.length - 1];
        int i = RandomInt(0, arr.length - 1);
        for (int i1 = 0; i1 < i; i1++) {
            ints[i1] = arr[i1];
        }
        for (int i2 = i + 1; i2 < arr.length; i2++) {
            ints[i2 - 1] = arr[i2];
        }
        hm.put(arr[i], ints);
        return hm;
    }

    /**
     * @param arr 传入一个数组，,double类型的，但是怎么简化呢
     * @return 返回一个值和数组的 集合 为什么返回值，因为这个值是hashmap的键，可以根据这个键查value
     */
    public static HashMap<Double, double[]> RandomArrayAndFigure(double[] arr) {
        HashMap<Double, double[]> hm = new HashMap<>();
        double[] dobs = new double[arr.length - 1];
        int i = RandomInt(0, arr.length - 1);
        for (int i1 = 0; i1 < i; i1++) {
            dobs[i1] = arr[i1];
        }
        for (int i2 = i + 1; i2 < arr.length; i2++) {
            dobs[i2 - 1] = arr[i2];
        }
        hm.put(arr[i], dobs);
        return hm;
    }
}
